package com.jtw.common.exception;


import com.jtw.common.bean.Result.Message;
import com.jtw.common.bean.enums.ReqCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * Created by keliii on 2018/7/17.
 * DESCRIPT: 统一异常处理类
 */
@RestControllerAdvice
@Slf4j
public class BaseExceptionHandler {

    /**
     * 自定义异常
     */
    @ExceptionHandler(BaseException.class)
    public Message cBaseException(BaseException exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        Message result = Message.getFailure();
        result.setCode(exception.getCode());
        result.setMessage(exception.getMessage());
        result.setData(exception.getData());
        return result;
    }

    /**
     * RequestParam的required校验异常
     * @param exception
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Message cMissingServletRequestParameterException( MissingServletRequestParameterException exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        return ReqCode.ParamsValidError.getMessage();
    }


    /**
     * 参数校验异常
     */
    @ExceptionHandler(BindException.class)
    public Message cValidException(BindException exception) {
        log.error(exception.getMessage());
        exception.printStackTrace();
        List<FieldError> fieldErrors = exception.getFieldErrors();
        for (FieldError fieldError : fieldErrors) {
            return ReqCode.ParamsValidError.getMessage(fieldError.getDefaultMessage());
        }
        return ReqCode.ParamsValidError.getMessage();
    }
    /**
     * 请求类型不支持错误
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Message cHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        log.error(exception.getMessage());
        exception.printStackTrace();
        return ReqCode.NotSupportMethod.getMessage();
//        return ReqCode.NotSupportMethod.getMessage(exception.getMessage());
    }
    /**
     * 主键字段冲突
     *
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public Message cDuplicateKeyException(DuplicateKeyException exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        return ReqCode.DuplicateKeyException.getMessage();
//        return ReqCode.DuplicateKeyException.getMessage(exception.getCause().getMessage());
    }
//    /**
//     * 数据库操作出错
//     */
//    @ExceptionHandler(DataIntegrityViolationException.class)
//    public Message cDataIntegrityViolationException(DataIntegrityViolationException exception) {
//        log.error(exception.getMessage());
//        return ReqCode.OutOfRangeException.getMessage();
//    }

    /**
     * 参数校验异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Message cConstraintValidException(ConstraintViolationException exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        Set<ConstraintViolation<?>> violatioins = exception.getConstraintViolations();
        String s = "";
        for (ConstraintViolation violation : violatioins) {
            s+=violation.getMessage();
        }
        return ReqCode.ParamsValidError.getMessage(s);
    }

    /**
     * 其他未知异常
     */
    @ExceptionHandler
    public Message cOtherException(Exception exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        log.error(exception.getCause().getMessage());
        return ReqCode.UnKnowException.getMessage();
    }
}
